package com.net.core.core.sql;

import com.net.core.core.YXException;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

public class YxSql {

    public StringBuffer sql;
    List<Object> values = new ArrayList<>();
    boolean lastK = false;

    private boolean isLog = true;

    public boolean isLog() {
        return isLog;
    }

    public void setLog(boolean log) {
        isLog = log;
    }

    public YxSql(String s) {
        sql = new StringBuffer(s);
        sql.append(" ");
    }

    public YxSql() {
        sql = new StringBuffer();
    }

    public YxSql append(Object s) {
        sql.append(" ").append(s).append(" ");
        return this;
    }

    /**
     * mybatis 专用
     *
     * @return
     */
    public Map<String, Object> getMaps() {
        Map<String, Object> data = new HashMap<>();
        for (int i = 0; i < values.size(); i++) {
            data.put(i + "", values.get(i));
        }
        return data;
    }

    protected String unionMybatisStr() {
        String str = sql.toString();
//        ================= Mybits 专用 =================
//        int len = getValues().length;
//        for (int i = 0; i < len; i++) {
//            str = str.replaceFirst("\\?", "#{map."+i+"}");
//        }
//        ==============================================
        return str.trim();
    }

    public String toSql() {
        String str = sql.toString();
        return str.trim();
    }

    protected String unionStr() {
        String str = sql.toString();
        return str.trim();
    }

    public YxSql append(String s, Object... keys) {
        List<Object> temp = new ArrayList<>();
        for (Object key : keys) {
            if (StringUtils.isNotBlank(key.toString()) && !key.toString().contains("null")) {
                temp.add(key);
            } else {
                throw new YXException("参数异常");
            }
        }
        append(s);
        values.addAll(temp);
        return this;
    }

    public YxSql notNullAppend(String s, Object... keys) {
        boolean isOk = true;
        List<Object> temp = new ArrayList<>();
        for (Object key : keys) {
            if (StringUtils.isNotBlank(key.toString()) && !key.toString().contains("null")) {
                temp.add(key);
            } else {
                isOk = false;
                break;
            }
        }
        if (isOk) {
            append(s);
            values.addAll(temp);
        }
        return this;
    }


    public Object[] getValues() {
        return values.toArray();
    }

    public List<Object> getValueList() {
        return values;
    }


    public YxSql addValue(Object... value) {
        List<Object> tbList = Arrays.asList(value);
        tbList.forEach(k -> values.add(k));
        return this;
    }

    public void clean() {
        sql = new StringBuffer();
        values.clear();
    }

    public void cleanValues() {
        values.clear();
    }

    protected void delLast(String flag) {
        int i1 = sql.lastIndexOf(flag);
        String s = sql.toString().trim();
        int i = s.lastIndexOf(flag);
        if (i != -1) {
            int len = s.length();
            int len1 = i + flag.length();
            if (len == len1) {
                sql.delete(i1, i1 + flag.length());
            }
        }
    }

    public static <T> List<T> MapToObj(List<Map<String, Object>> results, Class<T> clz) {
        List<T> list = new ArrayList<>();
        try {
            if (results.size() == 0) return list;
            Map<String, Field> proMap = new HashMap<>();
            for (Field curField : clz.getDeclaredFields()) {
                String key = null;
                TableField annotation = curField.getAnnotation(TableField.class);
                if (annotation != null) {
                    key = annotation.value();
                } else if (key == null) {
                    TableId annotation1 = curField.getAnnotation(TableId.class);
                    if (annotation1 != null) key = annotation1.value();
                }
                if (key == null || key.length() == 0) {
                    key = curField.getName();
                }
                Field lastField = proMap.put(key.toLowerCase(), curField);
                if (lastField != null) {
                    throw new YXException(key + " 存在同名称的注解=======================================");
                }
            }
            for (Map<String, Object> map : results) {
                T t = clz.newInstance();
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    Field field = proMap.get(entry.getKey().toLowerCase());
                    if (field != null) {
                        field.setAccessible(true);
                        //判断是否存在注解
                        if (field.getType().equals(String.class)) {
                            field.set(t, entry.getValue().toString());
                        } else {
                            field.set(t, entry.getValue());
                        }
                    }
                }
                list.add(t);
            }
        } catch (Exception e) {
            throw new YXException(e.getMessage(), e);
        }
        return list;
    }

    public YxSql param(String param) {
        sql.append("\"").append(param).append("\"");
        return this;
    }

}
